 /***************************************************************************
 *   Copyright (C) 2010 by ZhangShine , All Rights Reserved                                  
 *   zhangshine0125@gmail.com                                              
 *                                                                         
 *   This program is free software; you can redistribute it and/or modify  
 *   it under the terms of the GNU General Public License as published by  
 *   the Free Software Foundation; either version 2 of the License, or     
 *   (at your option) any later version.                                   
 *                                                                         
 *   This program is distributed in the hope that it will be useful,       
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         
 *   GNU General Public License for more details.                          
 *                                                                         
 *   You should have received a copy of the GNU General Public License     
 *   along with this program; if not, write to the                         
 *   Free Software Foundation, Inc.,                                       
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             
 ***************************************************************************/

#include "sinaparserxml.h"
#include <QtXml>

SinaParserXml::SinaParserXml()
{
//    this->xml = content;
//    this->account = account;
}

bool SinaParserXml::parserSinaAccountInformation(Account *account, QString &xmlContent)
{
    QDomDocument doc;
    QString errorStr;/* Error message */
    int errorLine;
    int errorCol;
    if(!doc.setContent(xmlContent,true,&errorStr,&errorLine,&errorCol))
    {
        //Deal error
        return false;
    }
    QDomElement root = doc.documentElement(); /* root element */
    QDomNodeList nodes = root.childNodes();
    for(uint i=0; i<nodes.length(); i++)
    {
        QDomNode node = nodes.at(i);
        if(node.isElement())
        {
            QDomElement element = node.toElement();
            fillAccount(account,element.tagName(), element.text());
        }
    }
    return true;
}

void SinaParserXml::fillAccount(Account *account, QString tagName, QString text)
{
    if(tagName=="id")
        account->setId(text);
    else if(tagName=="screen_name")
        account->setScreenName(text);
    else if(tagName=="name")
        account->setName(text);
    else if(tagName=="profile_image_url")
        account->setProfileImageUrl(text);
    else if(tagName=="friends_count")
        account->setFriends(text.toInt());
    else if(tagName=="followers_count")
        account->setFollower(text.toInt());
    else if(tagName=="statuses_count")
        account->setWeiboCount(text.toInt());
    else if(tagName=="verified")
    {
        if(text=="true")
            account->setVerified(true);
        else
            account->setVerified(false);
    }
}

bool SinaParserXml::parserStatusXml(QString &content, QList<Status> &statusList, 
                                    QMap<QString, Status> &retwStatusMap)
{
    QDomDocument doc;
    QString errorStr;
    int errorLine;
    int errorCol;
    if(!doc.setContent(content,true,&errorStr, &errorLine, &errorCol))
    {
        return false;
    }
    QDomElement root = doc.documentElement();
    QDomNodeList nodes = root.elementsByTagName("status");
    for(uint i=0; i<nodes.length(); i++)
    {
        Status status;
        Status retwStatus;
        QDomNode node = nodes.at(i);
        if(node.isElement())
        {
            QDomElement element = node.toElement();
            parserStatus(element, status, retwStatus);
            status.setRetweetedId(retwStatus.getId());
            statusList.append(status);
            retwStatusMap.insert(retwStatus.getId(), retwStatus);
        }
    }
    return true;
}

void SinaParserXml::parserUnreadXml(QString &xmlContent, int &statusUnread, int &atMeMentionsUnread, 
                                    int &commentUnread, int &directMessageUnread, int &newFollower)
{
//    statusUnread = 0; atMeMentionsUnread = 0;
//    commentUnread = 0; directMessageUnread = 0; newFollower = 0;
    QDomDocument doc; QString errorStr; int errorLine; int errorCol;
    if(!doc.setContent(xmlContent,true,&errorStr, &errorLine, &errorCol))
        return;
    //QDomElement root = doc.documentElement();
    QDomNodeList nodes = doc.documentElement().childNodes();
    for( uint i=0; i<nodes.length(); i++)
    {
        QDomNode node = nodes.at(i);
        QDomElement element = node.toElement();
        if(element.tagName()=="new_status")
            statusUnread += element.text().toInt();
        else if(element.tagName()=="followers")
            newFollower += element.text().toInt();
        else if(element.tagName()=="dm")
            directMessageUnread += element.text().toInt();
        else if(element.tagName()=="mentions")
            atMeMentionsUnread += element.text().toInt();
        else if(element.tagName() == "comments")
            commentUnread += element.text().toInt();
    }
}

bool SinaParserXml::parserCommentTimeline(QString &content, QList<Status> &commentList, 
                                          QMap<QString, Status> &retwCommentMap)
{
    QDomDocument doc;
    QString errorStr;
    int errorLine;
    int errorCol;
    if(!doc.setContent(content,true,&errorStr, &errorLine, &errorCol))
    {
        return false;
    }
    QDomElement root = doc.documentElement();
    QDomNodeList nodes = root.elementsByTagName("comment");
    for(uint i=0; i<nodes.length(); i++)
    {
        Status status;
        Status retwStatus;
        QDomNode node = nodes.at(i);
        if(node.isElement())
        {
            QDomElement element = node.toElement();
            parserCommentStatus(element, status, retwStatus);
            status.setRetweetedId(retwStatus.getId());
            commentList.append(status);
            retwCommentMap.insert(status.getRetweetedId(), retwStatus);
        }
    }
    return true;
}

void SinaParserXml::parserDirectMessage(QString &xmlContent, QList<Status> &directMessageList)
{
    QDomDocument doc; QString errorStr; int errorLine; int errorCol;
    if(!doc.setContent(xmlContent,true, &errorStr, &errorLine, &errorCol))
        return;
    QDomElement root = doc.documentElement();
    QDomNodeList nodes = root.elementsByTagName("direct_message");
    for( uint i=0; i<nodes.length(); i++)
    {
        Status status;
        QDomNode node = nodes.at(i);
        QDomElement element = node.toElement();
        parserDM(element, status);
        directMessageList.append(status);
    }
}

void SinaParserXml::parserDM(QDomElement &messageElement, Status &status)
{
    QDomNodeList messageNodes = messageElement.childNodes();
    for( uint j=0; j<messageNodes.length(); j++)
    {
        QDomNode node = messageNodes.at(j);
        QDomElement element = node.toElement();
        if(element.tagName()=="sender")
        {
            QDomNodeList senderNodes = element.childNodes();
            for( uint i=0; i<senderNodes.length(); i++)
            {
                QDomElement senderElement = senderNodes.at(i).toElement();
                fillSender(status, senderElement.tagName(), senderElement.text());
            }
            
        }
        else
            fillMessage(status, element.tagName(), element.text());
    }
}

void SinaParserXml::fillSender(Status &status, QString tagName, QString text)
{
    if(tagName=="id")
        status.setUserId(text);
    else if(tagName=="screen_name")
        status.setUserName(text);
    else if(tagName=="profile_image_url")
        status.setUserProfileImageUrl(text);
}

void SinaParserXml::fillMessage(Status &status, QString tagName, QString text)
{
    if(tagName=="id")
        status.setId(text);
    else if(tagName=="created_at")
    {
        QLocale lo(QLocale::C);
        QDateTime dateTime = lo.toDateTime(text, "ddd MMM dd HH:mm:ss +0800 yyyy");
        status.setCreatedAt(dateTime);
    }
    else if(tagName=="text")
        status.setText(text);
}

bool SinaParserXml::parserCommentStatus(QDomElement &statusElement, Status &status, Status &retwStatus)
{
    QDomNodeList statusNodes = statusElement.childNodes();
    for(uint j=0; j<statusNodes.length(); j++)
    {
        QDomNode node = statusNodes.at(j);
        if(node.isElement())
        {
            QDomElement element = node.toElement();
            if(element.tagName()=="user")
                parserUserInfo(status, element.childNodes());
            else if(element.tagName()=="status")
                retwStatus = parserRetweetedStatus(element.childNodes());
            else
                fillStatus(status, element.tagName(), element.text());
        }
    }
    return true;
}

/* parser a status */
bool SinaParserXml::parserStatus(QDomElement &statusElement,Status &status,Status &retwStatus)
{
    QDomNodeList statusNodes = statusElement.childNodes();
    for(uint j=0; j<statusNodes.length(); j++)
    {
        QDomNode node = statusNodes.at(j);
        if(node.isElement())
        {
            QDomElement element = node.toElement();
            if(element.tagName()=="user")
                parserUserInfo(status, element.childNodes());
            else if(element.tagName()=="retweeted_status")
                retwStatus = parserRetweetedStatus( element.childNodes());
            else
                fillStatus(status, element.tagName(), element.text());
        }
    }
    return true;
}

void SinaParserXml::fillUserInfo(Status &status, QString tagName, QString text)
{
    if(tagName=="screen_name")
        status.setUserName(text);
    else if(tagName=="id")
        status.setUserId(text);
    else if(tagName=="profile_image_url")
        status.setUserProfileImageUrl(text);
}

Status SinaParserXml::parserRetweetedStatus(QDomNodeList nodes)
{
    Status retweetedStatus;
    for( uint k=0; k<nodes.length(); k++)
    {
        QDomElement element = nodes.at(k).toElement();
        if(element.tagName()=="user")
            parserUserInfo(retweetedStatus, element.childNodes());
        else
            fillStatus(retweetedStatus, element.tagName(), element.text());
    }
    return retweetedStatus;
}

void SinaParserXml::fillStatus(Status &status, QString tagName, QString text)
{
    if(tagName=="created_at")
    {
        QLocale lo(QLocale::C);
        QDateTime dateTime = lo.toDateTime(text, "ddd MMM dd HH:mm:ss +0800 yyyy");
        status.setCreatedAt(dateTime);
    }
    else if(tagName=="id")
        status.setId(text);
    else if(tagName=="text")
        status.setText(text);
    else if(tagName=="favorited")
    {
        if(text=="false")
            status.setFavourited(false);
        else
            status.setFavourited(true);
    }
    else if(tagName=="thumbnail_pic")
        status.setThumbnailPic(text);
    else if(tagName=="bmiddle_pic")
        status.setBmiddlePic(text);
    else if(tagName=="original_pic")
        status.setOriginalPic(text);
}

bool SinaParserXml::parserUserInfo(Status &status, QDomNodeList nodes)
{
    for( uint i=0; i<nodes.length(); i++)
    {
        QDomElement element = nodes.at(i).toElement();
        fillUserInfo(status, element.tagName(), element.text());
    }
    return true;
}

void SinaParserXml::parserEmotions(QString &xmlContent, QList<Emotion> &emotionList)
{
    QDomDocument doc;
    QString errorStr;
    int errorLine;
    int errorCol;
    if(!doc.setContent(xmlContent,true,&errorStr, &errorLine, &errorCol))
    {
        return;
    }
    QDomElement root = doc.documentElement();
    QDomNodeList nodes = root.elementsByTagName("emotion");
    for(uint i=0; i<nodes.length(); i++)
    {
        Emotion emotion;
        QDomNodeList nodesList = nodes.at(i).toElement().childNodes();
        for(uint j=0; j<nodesList.length(); j++)
            fillEmotion(emotion, nodesList.at(j).toElement().tagName(), nodesList.at(j).toElement().text());
        emotionList.append(emotion);
    }
}

void SinaParserXml::fillEmotion(Emotion &emotion, QString tagName, QString text)
{
    if(tagName=="phrase")
        emotion.setPhrase(text);
    else if(tagName=="url")
        emotion.setUrl(text);
    else if(tagName=="category")
        emotion.setCategory(text);
    else if(tagName=="is_hot")
    {
        if(text=="true")
            emotion.setHot(true);
        else
            emotion.setHot(false);
    }
}
